package com.fowo.api.syncLingxingApi.service.syncImpl;


import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.dynamic.datasource.annotation.DS;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.fowo.api.datainterface.util.JsonUtil;
import com.fowo.api.entity.Product;
import com.fowo.api.syncLingxingApi.entity.*;
import com.fowo.api.syncLingxingApi.service.SyncBaseService;
import com.fowo.api.syncLingxingApi.service.impl.TmpSyncLingxingToAuxListAuxRelationProductServiceImpl;
import com.fowo.api.syncLingxingApi.service.impl.TmpSyncLingxingToAuxServiceImpl;
import com.fowo.api.sys.annotation.RedisSyncLock;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;


@Service
@Slf4j
@DS("ds24")
public class SyncAuxListServiceImpl extends SyncBaseService {

    private final static Integer MAX_LEN = 1000; //分页上线

    @Resource
    private TmpSyncLingxingToAuxServiceImpl tmpSyncLingxingToAuxListService;

    @Resource
    private TmpSyncLingxingToAuxListAuxRelationProductServiceImpl tmpSyncLingxingToAuxListAuxRelationProductService;

    public SyncAuxListServiceImpl() {
        super("auxListUrl", 200);
    }

    @RedisSyncLock(value = "SyncAuxListServiceImpl_mainLoop", timeout = 1000)
    @Transactional
    public void mainLoop(JSONObject object) throws Exception {
        long start_time_ms = System.currentTimeMillis();
        log.info("初始化操作, 清空临时表数据.");
        if (!super.initData()) {
            log.error("获取token失败.");
            return;
        }
        if (this.lxApiToken == null) return;
        int cur_offset = 0;
        int totalNum = 1;
        // 清空临时表数据
        tmpSyncLingxingToAuxListService.deleteAll();
        final String key = StrUtil.format("{}:{}", catchKey, data_version);
        while (totalNum >= cur_offset) {
            long block_start_time_ms = System.currentTimeMillis();
            JSONObject results = this.pullLingxingData(cur_offset, MAX_LEN);
            if (ObjUtil.isNotEmpty(results) && MapUtil.getInt(results, "code") == 0) {
                totalNum = MapUtil.getInt(results, "total");
                List<TmpSyncLingxingToAuxList> tmpProductList = JsonUtil.getJsonToList(MapUtil.getStr(results, "data"), TmpSyncLingxingToAuxList.class);
                List<String> auxList = new ArrayList<>();
                for (TmpSyncLingxingToAuxList tmpPr : tmpProductList) {
                    auxList.add(tmpPr.getSku());
                    //初始化赋值
                    tmpPr.init();
                    tmpPr.set_version(this.data_version);
                    tmpPr.setId(IdUtil.getSnowflakeNextId());
                    // 关联产品处理
                    tmpPr.setAuxRelationProductMirror(this.auxRelationProductMirrorFilter(tmpPr, tmpPr.getAuxRelationProduct()));
                    // 供应商报价信息处理
                    tmpPr.setPurchaseSupplierQuoteMirror(this.purchaseSupplierQuoteMirrorFilter(tmpPr, tmpPr.getPurchaseSupplierQuote()));

                }
                List<Product> oldProducts = searchOldData(auxList);
                log.info("比较新旧数据");
                List<TmpSyncLingxingToAuxList> cmpResults = compareNewOrOldDataAux(tmpProductList, oldProducts);
                // 插入临时表
                tmpSyncLingxingToAuxListService.saveBatch(cmpResults);
                // 插入属性临时表
                List<TmpSyncLingxingToAuxListAuxRelationProduct> skuList = cmpResults.stream().flatMap(fm -> CollUtil.isEmpty(fm.getAuxRelationProductMirror()) ? Stream.empty() : fm.getAuxRelationProductMirror().stream()).collect(Collectors.toList());
                tmpSyncLingxingToAuxListAuxRelationProductService.saveBatch(skuList);
                log.info("插入aux临时表，数量：" + Convert.toStr(cmpResults.size()) + "插入关联产品临时表，数量：" + Convert.toStr(skuList.size()));
                long currentTimeMillis = System.currentTimeMillis();
                log.info("拉取数据：" + Convert.toStr(cur_offset) + "/" + Convert.toStr(totalNum) + "。用时" +
                        Convert.toStr(currentTimeMillis - block_start_time_ms) + "毫秒。总用时" +
                        Convert.toStr(currentTimeMillis - start_time_ms) + "毫秒");
            } else {
                // MARK BUG
                log.error("拉取产品数据失败. offset=" + Convert.toStr(cur_offset) + ".");
            }
            cur_offset += MAX_LEN;
        }
        saveTempToFormal();
    }

    private List<TmpSyncLingxingToAuxListPurchaseSupplierQuote> purchaseSupplierQuoteMirrorFilter(TmpSyncLingxingToAuxList tmpPr, String purchaseSupplierQuote) {
        //todo 无数据,暂不处理
        return null;
    }

    private List<TmpSyncLingxingToAuxListAuxRelationProduct> auxRelationProductMirrorFilter(TmpSyncLingxingToAuxList tmpPr, String auxRelationProduct) {
        if (StrUtil.isEmpty(auxRelationProduct)) {
            return null;
        }
        List<TmpSyncLingxingToAuxListAuxRelationProduct> list = JsonUtil.getJsonToList(auxRelationProduct, TmpSyncLingxingToAuxListAuxRelationProduct.class);
        if (CollUtil.isEmpty(list)) {
            return null;
        }
        for (TmpSyncLingxingToAuxListAuxRelationProduct item : list) {
            item.setParentId(tmpPr.getId());
            item.set_version(this.data_version);
            item.setAccessoriesSkuMirror(tmpPr.getSku());
            item.setAccessoriesNameMirror(tmpPr.getProductName());
            item.setPurchaseCostMirror(tmpPr.getCgPrice());
        }
        return list;
    }

    protected void saveTempToFormal() {
        // 新增产品表
        tmpSyncLingxingToAuxListService.insertAuxList(this.data_version);
        tmpSyncLingxingToAuxListService.insertAuxListAuxRelationProduct(this.data_version);
//        tmpSyncLingxingToAuxListService.insertAuxListPurchaseSupplierQuote(this.data_version);
    }

    public JSONObject pullLingxingData(Integer offset, Integer length
    ) {
        Map<String, Object> requestBody = new HashMap<>();
        if (offset > 0) requestBody.put("offset", offset);
        if (length > 0) requestBody.put("length", length);
        return tryRequestLingxingApi(requestBody, super.lxApiUrl);
    }

    public List<Product> searchOldData(List<String> skus) {
        QueryWrapper<Product> queryWrapper = new QueryWrapper<>();
        queryWrapper.in("sku", skus);
        return productService.list(queryWrapper);
    }


}
